﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BigPang.Common.GamePlay.Objects;
using BigPang.Render;
using System.Threading.Tasks;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace BigPang.Game.Objects
{
    public class CTank : Tank
    {
        [DllImport("user32.dll")]
        private static extern short GetAsyncKeyState(Keys key);

        bool mIsGod;
        int mGodStartTime;
        int mBulletTime;

        int mHp = 3;

        Sprite bulletSprite;

        int mSoccer;
        Keys keyValue;

        public int Soccer
        {
            get { return mSoccer; }
            set { mSoccer = value; mSprite.HUD = Name + ": " + mSoccer.ToString(); }
        }

        public bool IsGod
        {
            get
            {
                return mIsGod;
            }

            set
            {
                if (value)
                {
                    mGodEffect.RegisterRender();
                    mSprite.MountEffect = mGodEffect;
                }
                else
                {
                    mSprite.MountEffect = null;
                    mGodEffect.UnregisterRender();
                }

                mIsGod = value;
            }
        }


        public enum Action
        {
            Fire,
        }

        public override int X
        {
            get
            {
                return mSprite.RenderPosition.X;
            }
            set
            {
                mSprite.SetPosition(value, Y);
            }
        }

        public override int Y
        {
            get
            {
                return mSprite.RenderPosition.Y;
            }
            set
            {
                mSprite.SetPosition(X, value);
            }
        }

        public Sprite mSprite;
        Effect mGodEffect;
        bool isFiring = false;

        public static CTank mControlTank;

        public override void OnAdd()
        {
            mGodEffect = new Effect("./ResData/GOD_1.png", 10, 3, true);
            bulletSprite = new Sprite("./ResData/BULLET_1.png", 1);
            bulletSprite.OnHit += new EventHandler<SpriteHitEventArgs>(bulletSprite_OnHit);

            mSprite = new Sprite("./ResData/TANK_1.png");
            mSprite.Tag = this;
            mSprite.mLayer = 1;
            mSprite.RegisterRender();
            mSprite.HUD = Name + ":";

            bulletSprite.mSource = mSprite;

            if (Program.mObjId == Id)
                TakeControl();

            Canvas.MainCanvas.Camrea.AddShake(20);
        }

        public void TakeControl()
        {
            MainForm.mTestSprite = mSprite;
            mControlTank = this;
            Program.mObjId = Id;


        }

        public void OnHit(CTank source)
        {
            mHp -= 1;
            if (mHp < 0)
            {


                int x = new Random(Environment.TickCount).Next(20);
                int y = new Random(Environment.TickCount).Next(10);
                mSprite.SetPosition(x * Map.TileSize, y * Map.TileSize);
                //bulletSprite.UnregisterRender();
                //isFiring = false;
                //bulletSprite.StopMove();

                IsGod = true;
                mGodStartTime = Environment.TickCount;

                source.Soccer += 10;
                Canvas.MainCanvas.Camrea.AddShake(20);
                mHp = 3;
            }
            else
            {
                Canvas.MainCanvas.Camrea.AddShake(10);
                source.Soccer += 2;
            }
        }

        public override async void OnProcessTick()
        {
            if (Id == Program.mObjId)
            {
                if( ( GetAsyncKeyState( Keys.Space ) & 0x8000 ) > 0 )
                {
                    if( !isFiring )
                        await TaskEx.Run(() => { Program.mGameService.Action(0); });
                    
                    return;
                }

                Sprite.Direction dir = Sprite.Direction.Unknown;
                Keys key = Keys.Clear;

                if ((GetAsyncKeyState(Keys.W) & 0x8000) > 0)
                {
                    key = Keys.W;
                    dir = Sprite.Direction.Up;
                }

                if ((GetAsyncKeyState(Keys.S) & 0x8000) > 0)
                {
                    key = Keys.S; 
                    dir = Sprite.Direction.Down;
                }

                if ((GetAsyncKeyState(Keys.A) & 0x8000) > 0)
                {
                    key = Keys.A; 
                    dir = Sprite.Direction.Left;
                }

                if ((GetAsyncKeyState(Keys.D) & 0x8000) > 0)
                {
                    key = Keys.D; 
                    dir = Sprite.Direction.Right;
                }

                if (dir == Sprite.Direction.Unknown)
                {
                    // key up
                    if (mSprite.IsMoving)
                    {
                        mSprite.StopMove();
                        await TaskEx.Run(() => { Program.mGameService.StopMove(mSprite.RenderPosition.X, mSprite.RenderPosition.Y); });
                    }
                    return;
                }

                if (key != keyValue)
                {
                    if (mSprite.IsMoving)
                    {
                        mSprite.StopMove();
                        await TaskEx.Run(() => { Program.mGameService.StopMove(mSprite.RenderPosition.X, mSprite.RenderPosition.Y); });
                    }

                    mSprite.StartMove(dir, 100);
                    await TaskEx.Run(() => { Program.mGameService.StartMove(mSprite.RenderPosition.X, mSprite.RenderPosition.Y, (int)dir, 100); });
                    keyValue = key;
                }
                else
                {
                    if (!mSprite.IsMoving)
                    {
                        mSprite.StartMove(dir, 100);
                        await TaskEx.Run(() => { Program.mGameService.StartMove(mSprite.RenderPosition.X, mSprite.RenderPosition.Y, (int)dir, 100); });
                    }
                    else
                    {

                    }
                }
            }

            if (IsGod)
            {
                if (Environment.TickCount - mGodStartTime >= 1000)
                {
                    IsGod = false;
                }
            }

            if (isFiring)
            {
                if (Environment.TickCount - mBulletTime >= 1000)
                {
                    isFiring = false;
                    bulletSprite.UnregisterRender();
                    bulletSprite.StopMove();
                }
            }

            //if (Program.mObjId == Id)
            //{
            //    Point p = mSprite.RenderPosition;

            //    p.X /= Map.TileSize;
            //    p.Y /= Map.TileSize;

            //    Point pl = p;

            //    switch (mSprite.mDirection)
            //    {
            //        case Sprite.Direction.Left:
            //            p.X -= 1;
            //            break;
            //        case Sprite.Direction.Right:
            //            p.X += 1;
            //            break;
            //        case Sprite.Direction.Down:
            //            p.Y += 1;
            //            break;
            //        case Sprite.Direction.Up:
            //            p.Y -= 1;
            //            break;
            //    }

            //    if (Map.TheMap != null)
            //    {
            //        try
            //        {
            //            if (!Map.TheMap.CanPass(p.X, p.Y))
            //            {
            //                TaskEx.Run(() => { Program.mGameService.StopMove(mSprite.RenderPosition.X, mSprite.RenderPosition.Y); });
            //            }

            //        }
            //        catch
            //        {
            //            TaskEx.Run(() => { Program.mGameService.StopMove(mSprite.RenderPosition.X, mSprite.RenderPosition.Y); });
            //        }
            //    }
            //}
        }

        public override void SetPosition(int x, int y)
        {
            base.SetPosition(x, y);

            mSprite.SetPosition(x, y);
        }

        public void OnAction(Action act)
        {
            switch (act)
            {
                case Action.Fire:
                    {
                        if (isFiring)
                            break;

                        isFiring = true;
                        mBulletTime = Environment.TickCount;

                        Point p = mSprite.RenderPosition;
                        int x = p.X + mSprite.Size.Width / 2 - bulletSprite.Size.Width / 2;
                        int y = p.Y + mSprite.Size.Height / 2 - bulletSprite.Size.Height / 2;

                        bulletSprite.SetPosition(x, y);
                        bulletSprite.RegisterRender();

                        bulletSprite.StartMove(mSprite.mDirection, 500);
                        bulletSprite.Tag = this;
                    }
                    break;
            }
        }

        async void bulletSprite_OnHit(object sender, SpriteHitEventArgs e)
        {
            Sprite bulletSprite = sender as Sprite;
            bulletSprite.UnregisterRender();
            isFiring = false;
            bulletSprite.StopMove();

            CTank tank = e.Target.Tag as CTank;
            CTank sTank = bulletSprite.Tag as CTank;

            if (tank.IsGod)
                return;

            Effect effect = new Effect("./ResData/EXP_1.png", 10, 4);
            effect.SetPosition(tank.X, tank.Y);
            effect.RegisterRender();

            await TaskEx.Run(() => { Program.mGameService.Hit(tank.Id, sTank.Id); });
        }
    }
}
